package java8.atguigu.teacher.lambda02;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * @program lambda
 * @description:
 * @author: zhanglu
 * @create: 2019-05-26 19:01:00
 *
 * 左右遇一括号省，
 * 左侧推断类型省
 * 右侧一句返回省
 * 能省则省
 *
 * Lambda表达式需要函数式接口的支持
 *  函数式接口：若接口中只有一个抽象方法时，可以是使用注解修饰@FunctionalInterface，可以检查是否是函数式接口
 */
@Slf4j
public class TestLambda{

    /**
     * 无参数，无返回值
     */
    @Test
    public void test01(){
        int num = 0;    //jdk 必须是final，这里默认给加了
        Runnable r = () -> System.out.println("hellow  " + num);
        r.run();
    }

    /**
     * 有一个参数，无返回值(只有一个参数，小括号可以不写)
     */
    @Test
    public void test02(){
        Consumer<String> consumer = (e) -> System.out.println("hello " + e);
        consumer.accept("showlu");
    }

    /**
     * 有两个以上的参数，有返回值，并且lambda体中有多条语句(如果有多条语句，lambda体必须要加大括号)
     */
    @Test
    public void test03(){
        Comparator<Integer> com = (x, y) -> {
            System.out.println("函数式接口");
            return Integer.compare(x, y);
        };
        int res = com.compare(2,3);
        System.out.println(res);
    }

    //需求：对一个数进行运算
    @Test
    public void test04(){
        System.out.println(operation(100, (x) -> x * x));
        System.out.println(operation(200, x -> x + x));
    }

    public Integer operation(Integer num, MyFunction01 mf){
        return mf.getValue(num);
    }


    @Test
    public void test05() throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/Users/zhanglu/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/c9a1c762ab6161f8ffce2831a28327a2/Message/MessageTemp/cf53e98e21e0e5a4524e375f812e9d64/File/1.txt"),"utf-8"));
        String line = "";
        String res = "";
        while((line = br.readLine()) != null){
            res += line;
        }
        Map m1 = JSONObject.parseObject(res, Map.class);
        List<Map> lms = (List<Map>) m1.get("data");


        List<Map> deleteAllByCode = lms.stream().filter(o -> o.get("jdjgbm") != null).filter(distinctByKey(o -> o.get("jdjgbm"))).collect(Collectors.toList());
        //封装删除条目
        for (Map m : deleteAllByCode) {

        }

//        List<Map> lms2 = lms;
//
//        lms.stream().forEach(o1 -> {
//            AtomicReference<Integer> count = new AtomicReference<>(0);
//            Object s1 = o1.get("bh");
//            lms2.stream().forEach(o2 -> {
//                Object s2 = o2.get("bh");
//                if(s1.equals(s2)){
//                    count.getAndSet(count.get() + 1);
//                }
//            });
//            if(count.get() != 1){
//                Object temp = o1;
//                System.out.println(1);
//            }
//        });

        System.out.println(1);
    }

    //去重复
    private <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    @Test
    public void test06() throws InterruptedException {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            log.info("1");
        }, 0,2, TimeUnit.SECONDS);

        ScheduledExecutorService scheduledExecutorService2 = Executors.newScheduledThreadPool(1);
        scheduledExecutorService2.scheduleAtFixedRate(() -> {
            log.info("2");
        }, 0,2, TimeUnit.SECONDS);

//        scheduledExecutorService.scheduleWithFixedDelay(() -> {
//            log.info("2");
//        }, 2,1, TimeUnit.SECONDS);

//        scheduledExecutorService.schedule(() -> {
//            log.info("3");
//        }, 2, TimeUnit.SECONDS);

//        TimeUnit.SECONDS.sleep(10);
//
//        scheduledExecutorService.shutdown();

        while (true){}
    }

}
